package com.groupbuying.payconsumer.mq;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
import com.aliyun.openservices.shade.com.alibaba.fastjson.serializer.SerializerFeature;
import com.groupbuying.payconsumer.connector.OrderFeign;
import com.groupbuying.payconsumer.connector.SysconfigFeign;
import com.groupbuying.payconsumer.constants.CommonConstants;
import com.groupbuying.payconsumer.constants.PayAlipayResultEnumConstants;
import com.groupbuying.payconsumer.constants.PayInfoEnumConstants;
import com.groupbuying.payconsumer.domain.PayAlipayResultDO;
import com.groupbuying.payconsumer.domain.PayInfoDO;
import com.groupbuying.payconsumer.domain.PayOrderRelDO;
import com.groupbuying.payconsumer.service.PayAlipayResultService;
import com.groupbuying.payconsumer.service.PayInfoService;
import com.groupbuying.payconsumer.service.PayOrderRelService;
import com.groupbuying.payconsumer.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

//

/**
 * 支付中心支付宝消费者监听
 *
 * @Author Vincentxin
 * @Date 2019-05-10
 */
@Component
public class AliPayResult {
    public static final Logger LOGGER = LoggerFactory.getLogger(AliPayResult.class);

    @Autowired
    private PayInfoService payInfoService;

    @Autowired
    private PayOrderRelService payOrderRelService;

    @Autowired
    private PayAlipayResultService payAlipayResultService;

    @Autowired
    private Producer producer;

    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private SysconfigFeign sysconfigFeign;

    @Transactional(rollbackFor = Exception.class)
    public boolean dealResult(Map<String, Object> messageBody) {

        //存储支付回执信息
//        LOGGER.info("回执消息："+messageBody.toString());
        LOGGER.info("回执消息：{}" + messageBody.toString());
        PayAlipayResultDO payAlipayResultDO = new PayAlipayResultDO();
        payAlipayResultDO.setId(messageBody.get("out_trade_no").toString());
        payAlipayResultDO.setResultCode(messageBody.get("trade_status").toString());
        payAlipayResultDO.setTotalAmount(new BigDecimal(messageBody.get("total_amount").toString()));//支付金额
        payAlipayResultDO.setTradeNo(messageBody.get("trade_no").toString());
        payAlipayResultDO.setGmtCreate(new Date());

        try {
            payAlipayResultDO.setGmtPayment(DateUtils.parse(messageBody.get("gmt_payment").toString(), "yyyyMMddHHmmss"));
        } catch (ParseException e) {
            e.printStackTrace();
            LOGGER.info("时间：{}，订单号：{}，支付宝内部单号：{}，错误提示：{}",
                    DateUtils.format(new Date(), DateUtils.YMDHMS), payAlipayResultDO.getId(), payAlipayResultDO.getTradeNo(), "支付宝交易日期转换错误");
        }

        payAlipayResultDO.setGmtModified(new Date());
        payAlipayResultDO.setIsDelete(PayAlipayResultEnumConstants.ENUM_ISDELETE_UNDEL);
        try {
            payAlipayResultService.save(payAlipayResultDO);
        } catch (DuplicateKeyException exception) {
            //主键冲突之后，更新
            payAlipayResultService.update(payAlipayResultDO);
            LOGGER.info("时间：{}，订单号：{}，支付宝内部单号：{}，错误提示：{}",
                    DateUtils.format(new Date(), DateUtils.YMDHMS), payAlipayResultDO.getId(), payAlipayResultDO.getTradeNo(), "支付宝交易已经保存过了是多次请求");
        }

        //获取支付单信息
        PayInfoDO payInfoDO = payInfoService.get(payAlipayResultDO.getId());
        //判断回执金额和支付单金额不一致
        if (payInfoDO.getPayMoney().compareTo(payAlipayResultDO.getTotalAmount()) != 0) {
            //TODO 金额不一致对应的处理（作为异常订单处理），暂时记录日志，然后标记消费
            //TODO 发送订单中心冻结交（或许）
            LOGGER.info("时间：{}，订单号：{}，支付宝内部单号：{}，错误提示：{}",
                    DateUtils.format(new Date(), DateUtils.YMDHMS), payAlipayResultDO.getId(), payAlipayResultDO.getTradeNo(), "支付宝交易金额不一致");
            return true;
        }

        //支付状态确认并修改
        //支付宝未付款交易超时关闭，或支付完成后全额退款
//        if (PayAlipayResultEnumConstants.ENUM_RESULTCODE_CLOSED.equals(payAlipayResultDO.getResultCode())) {
//            //如果支付单的状态不是（未付款交易超时关闭，或支付完成后全额退款）
//            if (!PayAlipayResultEnumConstants.ENUM_RESULTCODE_CLOSED.equals(payInfoDO.getPayState())){
//                //强行修改支付单支付状态为（未付款交易超时关闭，或支付完成后全额退款）
//                payInfoDO.setPayState(PayAlipayResultEnumConstants.ENUM_RESULTCODE_CLOSED);
//                payInfoDO.setGmtModified(new Date());
//                payInfoService.save(payInfoDO);
//            }
//            LOGGER.info("订单号：" + payAlipayResultDO.getId() + "，支付宝内部单号：" + payAlipayResultDO.getTradeNo() + "未付款交易超时关闭，或支付完成后全额退款");
//            return true;
//        }
//        //支付宝交易创建，等待买家付款
//        else if (PayAlipayResultEnumConstants.ENUM_RESULTCODE_WAIT.equals(payAlipayResultDO.getResultCode())) {
//            //如果支付单的状态不是（交易创建，等待买家付款）
//            if (!PayAlipayResultEnumConstants.ENUM_RESULTCODE_WAIT.equals(payInfoDO.getPayState())){
//                //强行修改支付单支付状态为（交易创建，等待买家付款）
//                payInfoDO.setPayState(PayAlipayResultEnumConstants.ENUM_RESULTCODE_WAIT);
//                payInfoDO.setGmtModified(new Date());
//                payInfoService.save(payInfoDO);
//            }
//            LOGGER.info("订单号：" + payAlipayResultDO.getId() + "，支付宝内部单号：" + payAlipayResultDO.getTradeNo() + "交易创建，等待买家付款");
//            return true;
//        }
//        //支付宝交易结束，不可退款
//        else if (PayAlipayResultEnumConstants.ENUM_RESULTCODE_FINISHED.equals(payAlipayResultDO.getResultCode())) {
//            //如果支付单的状态不是（支付宝交易结束，不可退款）
//            if (!PayAlipayResultEnumConstants.ENUM_RESULTCODE_FINISHED.equals(payInfoDO.getPayState())){
//                //强行修改支付单支付状态为（支付宝交易结束，不可退款）
//                payInfoDO.setPayState(PayAlipayResultEnumConstants.ENUM_RESULTCODE_FINISHED);
//                payInfoDO.setGmtModified(new Date());
//                payInfoService.save(payInfoDO);
//            }
//            LOGGER.info("订单号：" + payAlipayResultDO.getId() + "，支付宝内部单号：" + payAlipayResultDO.getTradeNo() + "支付宝交易结束，不可退款");
//            return true;
//        }
        // 支付宝支付成功
        if (PayAlipayResultEnumConstants.ENUM_RESULTCODE_SUCCESS.equals(payAlipayResultDO.getResultCode())) {
            //查看当前支付单是否已经修改成功
            if (PayInfoEnumConstants.ENUM_PAYSTATE_SUCPAY.equals(payInfoDO.getPayState())) {
                return true;
            }
            payInfoDO.setPayState(PayInfoEnumConstants.ENUM_PAYSTATE_SUCPAY);
            payInfoDO.setGmtModified(new Date());
            payInfoService.save(payInfoDO);
        } else {
            LOGGER.info("时间：{}，第三方单号：{}，订单号：{}，支付宝内部单号：{}，状态：{}，错误提示：{}",
                    DateUtils.format(new Date(), DateUtils.YMDHMS), messageBody.get("out_trade_no"),
                    payAlipayResultDO.getId(), payAlipayResultDO.getTradeNo(), payAlipayResultDO.getResultCode(), "支付宝支付交易失败");
            return true;
        }

        //获取支付单与订单关联信息
        PayOrderRelDO payOrderRelDO = payOrderRelService.get(payAlipayResultDO.getId());
        //获取订单信息
        Map orderMap = orderFeign.getOrderForPay(payOrderRelDO.getOrderId());
        //订单是否属于够样优店
        boolean curNotify = orderMap.get("orderId").toString().substring(4, 7).equals("000");
        if (curNotify) {
            //商户优惠规则
            Map ruleMap = new HashMap();
            ruleMap.put("ruleId", orderMap.get("opxRuleId"));
            ruleMap.put("delFlag", CommonConstants.COMMON_FLAG_UNDEL);
            Map rulesMap = sysconfigFeign.getStoreOpexRule(ruleMap);
            orderMap.putAll(rulesMap);
        }

        //设置订单中心消息传递消息体
        Map<String, Object> orderParam = new HashMap<>();
        orderParam.put("orderId", orderMap.get("orderId"));
        //设置积分中心消息传递消息体
        Map<String, Object> currencyParam = new HashMap<>();
        if (curNotify) {
            currencyParam.put("payId", payInfoDO.getId());
            currencyParam.put("customerId", orderMap.get("customerId"));
            currencyParam.put("consumptionAmount", orderMap.get("orderPrice"));
            currencyParam.put("backCurrencyRatio", orderMap.get("backCurrencyRatio"));

        }
        //设置分账中心消息传递内容
        Map<String, Object> settleParam = new HashMap<>();
        settleParam.put("orderId", orderMap.get("orderId"));
        settleParam.put("outTradeNo", payOrderRelDO.getOutTradeNo());
        settleParam.put("ruleId", orderMap.get("opxRuleId"));
        settleParam.put("totalAmount", payInfoDO.getPayMoney());
        //收银台ID
        settleParam.put("counterId", orderMap.get("counterId"));
        //用户ID
        settleParam.put("customerId", orderMap.get("customerId"));
        //支付分账
        settleParam.put("settleType", "0");
        settleParam.put("payType", payInfoDO.getPayType());
        settleParam.put("payChannel", payInfoDO.getPayChannel());

        try {
            //订单中心
            Message orderMessage = new Message(PayMQConfig.ORDER_TOPIC, PayMQConfig.ORDER_TAG_PAY,
                    JSON.toJSONString(orderParam, SerializerFeature.DisableCircularReferenceDetect).getBytes());
            producer.send(orderMessage);
        } catch (Exception e) {
            LOGGER.error("订单号：{}，支付宝内部单号：{}，错误提示：{}", payAlipayResultDO.getId(), payAlipayResultDO.getTradeNo(), "发送订单中心失败");
            e.printStackTrace();

        }
        if (curNotify) {
            try {
                //积分中心
                Message currencyMessage = new Message(PayMQConfig.CURRENCY_TOPIC, PayMQConfig.CURRENCY_TAG_ADD,
                        JSON.toJSONString(currencyParam, SerializerFeature.DisableCircularReferenceDetect).getBytes());
                producer.send(currencyMessage);
            } catch (Exception e) {
                LOGGER.error("订单号：{}，支付宝内部单号：{}，错误提示：{}", payAlipayResultDO.getId(), payAlipayResultDO.getTradeNo(), "发送积分中心失败");
                e.printStackTrace();
            }
        }

        try {
            //分账中心
            Message settleMessage = new Message(PayMQConfig.SETTLE_TOPIC, PayMQConfig.SETTLE_TAG_SPLIT,
                    JSON.toJSONString(settleParam, SerializerFeature.DisableCircularReferenceDetect).getBytes());
            producer.send(settleMessage);
        } catch (Exception e) {
            LOGGER.error("订单号：{}，支付宝内部单号：{}，错误提示：{}", payAlipayResultDO.getId(), payAlipayResultDO.getTradeNo(), "发送分账中心失败");
            e.printStackTrace();
            //发送不成功的话，稍后重试
        }
        return true;
    }

}
